실제 기능을 수행하는 객체 대신 가상의 객체를 사용해 로직의 흐름을 제어하는 디자인 패턴
실제 클래스가 리소스 집약적인 경우에 사용됩니다.
예를들어, 실제 클래스가 해상도가 높은 이미지를 처리해야하는 경우 인스턴스화 할 때 많은 메모리를 사용하게 되는데, 이런 이미지들에 동시에 많은 접근이 이루어진다면 시스템에 부하가 많이 가게 됩니다.
프록시 클래스에서 자잘한 작업들을 처리하고 리소스가 많이 요구되는 작업들이 필요할 때에만 실제 클래스를 사용하도록 구현할 수 있습니다.
리소스 집약적인 객체가 실제로 필요해질 때까지 라이트한 버전의 프록시 인스턴스로 전처리 등 필요한 작업을 수행할 수 있습니다.
실제 클래스에 대한 접근을 제어하기 위한 경우에 사용됩니다.
프록시 클래스에서 클라이언트가 실제 클래스에 대한 접근을 허용할지 말지 결정하도록 할 수 있습니다. 어떤 접근 권한을 가지고 있는지에 따라 그에 맞는 주체 클래스의 메소드를 호출하도록 구현할 수 있습니다.
즉, 어떤 클랑이언트인지에 따라 서로 다른 방식으로 요청을 처리할 수 있습니다.
프록시 클래스는 로컬에 두고, 실제 클래스는 Remote로 존재하는 경우입니다.
즉 동일한 물리적, 또는 가상 공간에 있지 않은 시스템을 로컬 프록시를 통해 로컬에 있는 것처럼 표현하는 것입니다.
Google Docs가 대표적인 예시입니다. 브라우저는 브라우저대로 필요한 자원을 로컬에 가지고 있고, 또 다른 일부 자원은 Google 서버에 있는 형태입니다.
이미지를 load하고, display하는 과정을 Image 인터페이스를 통해 표현했습니다.
처음 load엔 시간이 걸린다고 생각하고 가상의 지연을 주었습니다. 코드로 확인할 수 있습니다.
loadFromDisk를 통해 객체의 fileName 필드에 fileName을 저장하고, display를 통해 load된 파일을 출력합니다.
실제 클래스에선 load할 때마다 지연이 발생하고, display 시 기존에 load된 파일이 있는지 확인하는 부분이 없습니다.
실제 클래스의 동작을 수행하기 전, 이미 load 되어있는 파일의 경우 다시 load하며 발생하는 시간 낭비를 방지할 수 있습니다.
추가적으로 display 하기 전 load된 파일이 있는지 확인을 통해 발생될 문제를 방지할 수 있습니다.
다양하게 수행을 거쳤습니다.
결과는 다음과 같습니다.
No files loaded
---------------
Load: image01.jpg
Display: image01.jpg
---------------
Display: image01.jpg
---------------
Load: image02.jpg
Display: image02.jpg
이미 load된 image01.jpg를 다시 load했으나 출력을 보면 load에 대한 수행은 중복되지 않았고, display만 수행된 것을 확인할 수 있습니다.
이처럼 자원관리 프록시를 이용하면 실제 객체가 비용이 많이 드는 자원을 생성할 때, 중복 생성을 방지해 자원을 효율적으로 이용할 수 있습니다.
위 예제는 다음 링크를 참조하였습니다. 추가적으로 다른 프록시에 대해 이해할 수 있는 예시 코드들이 있으니 참고하시면 좋을 것 같습니다.
참조
감사합니다.
Text by Chaelin. Photographs by Chaelin, Unsplash.